package org.ocean.hibernate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.ocean.online.constant.Constant;
import org.ocean.online.utils.CommonUtil;

public class CreateTableUtil {
	static Dialect dialect = new H2Dialect();
	public static void createTable(Table table ,Configuration config){
		
		String script = table.sqlCreateString(dialect,config.buildMapping(), null, null);
		if(script.contains("create table")){
			script = script.replace("create table", "create table if not exists");
		}
		System.out.println(script);
		Session ss = SessionFactoryUtil.getSysSessionFactory().openSession();
		Transaction tra = ss.beginTransaction();
		ss.createSQLQuery(script).executeUpdate();
		tra.commit();
	}
	public static List<String> getAddColSql(String tableName,List<Map> addCols){
		return getAlterColSql(tableName,addCols,"add column");
	}
	public static String getCreateTableSql(String tableName,List<Map> fields){
		Table table = buildTable(tableName, fields);
		if(table==null){
			return "";
		}
		String script = table.sqlCreateString(dialect,
				SessionFactoryUtil.getConfig().buildMapping(), null, null);
		if(script.contains("create table")){
			script = script.replace("create table", "create table if not exists");
		}
		return script;
	}
	
	private static Table buildTable(String tableName,List<Map> fields){
		if(tableName==null){
			return null;
		}
		Table table = new Table();
		table.setName(tableName);
		for(Map<String,Object> field:fields){
			MyColumn column = new MyColumn();
			if(field.get("oldAttrName")!=null){
				column.setOldColumnName(field.get("oldAttrName").toString());
			}
			column.setName(field.get(Constant.AttrName_VariableName).toString());
			column.setLength((field.get(Constant.AttrLength_VariableName)==null )?0:Integer.valueOf(field.get(Constant.AttrLength_VariableName).toString()));
			column.setNullable(field.get(Constant.Nullable_VariableName)==null?true: Boolean.valueOf(field.get(Constant.Nullable_VariableName).toString()));
			column.setComment(field.get(Constant.Commnent_VariableName)==null?"":field.get(Constant.Commnent_VariableName).toString());
//			SimpleValue value = new SimpleValue(SessionFactoryUtil.getConfig().createMappings(),table);
			SimpleValue value = new SimpleValue(table);
			value.setTypeName(CommonUtil.convertType(field.get(Constant.AttrType_VariableName).toString()));
			column.setValue(value);
			table.addColumn(column);
		}
		return table;
	}
	public static List<String> getDropColSql(String tableName, List<Map> dropCols) {
		List<String> scripts = new ArrayList<String>();
		for(Map col : dropCols){
			String sql= "alter table "+tableName +" drop column "+col.get(Constant.AttrName_VariableName);
			scripts.add(sql);
		}
		return scripts;
	}
	
	private static List<String> getAlterColSql(String tableName, List<Map> alterCols,String method) {
		List<String> script = new ArrayList<String>();
		Table table = buildTable(tableName, alterCols);
		if(table==null){
			return script;
		}
		StringBuffer root = new StringBuffer( "alter table " )
		.append( table.getQualifiedName( dialect, null, null ) )
		.append( ' ' )
		.append( method );

		Iterator iter = table.getColumnIterator();
		while ( iter.hasNext() ) {
			MyColumn column = (MyColumn) iter.next();

		// the column doesnt exist at all.
		StringBuffer alter = new StringBuffer( root.toString() )
				.append( ' ' );
		
		
		if(StringUtils.isNotBlank(column.getOldColumnName())){
			alter.append(column.getOldColumnName());
		}
		alter.append( ' ' );
		alter.append( column.getQuotedName( dialect ) );
		alter.append( ' ' )
				.append( column.getSqlType( dialect, SessionFactoryUtil.getConfig().buildMapping()));

		String defaultValue = column.getDefaultValue();
		if ( column.isNullable() ) {
			alter.append( dialect.getNullColumnString() );
		}
		else {
			alter.append( " not null" );
		}
		if ( defaultValue != null ) {
			alter.append( " default " ).append( defaultValue );
		}

		boolean useUniqueConstraint = column.isUnique() &&
				dialect.supportsUnique() &&
				( !column.isNullable() || dialect.supportsNotNullUnique() );
		if ( useUniqueConstraint ) {
			alter.append( " unique" );
		}

		if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
			alter.append( " check(" )
					.append( column.getCheckConstraint() )
					.append( ")" );
		}

		String columnComment = column.getComment();
		if ( columnComment != null ) {
			alter.append( dialect.getColumnComment( columnComment ) );
		}

		script.add( alter.toString() );
		}
		return script;
	}
	public static List<String> getAlterColSql(String tableName, List<Map> alterCols) {
		return getAlterColSql(tableName,alterCols,"change column");
	}
}
